﻿using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Encryption
{
    /// <summary>
    /// AES加解密
    /// </summary>
    public class AESEncryption
    {
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="text">原文</param>
        /// <param name="key">加密key</param>
        /// <param name="iv">加密key向量</param>
        /// <returns></returns>
        public static string Encrypt(string text, string key, string iv)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                throw new ArgumentNullException("text");
            }

            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException("key");
            }

            if (iv.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException("iv");
            }

            var inputByteArray = Encoding.UTF8.GetBytes(text);
            var cipherBytes = default(byte[]);

            using (var aes = Rijndael.Create())
            {
                //设置密钥及密钥向量
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Padding = PaddingMode.PKCS7;

                using (var memoryStream = new MemoryStream())
                {
                    using (var cryptoStream = new CryptoStream(memoryStream, aes.CreateEncryptor(), CryptoStreamMode.Write))
                    {
                        cryptoStream.Write(inputByteArray, 0, inputByteArray.Length);
                        cryptoStream.FlushFinalBlock();
                        cipherBytes = memoryStream.ToArray();

                        cryptoStream.Close();
                        memoryStream.Close();
                    }
                }
            }

            return Convert.ToBase64String(cipherBytes);
        }

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="text">密文</param>
        /// <param name="key">加密key</param>
        /// <param name="iv">加密key向量</param>
        /// <returns></returns>
        public static string Decrypt(string text, string key, string iv)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                throw new ArgumentNullException("text");
            }

            if (string.IsNullOrWhiteSpace(key))
            {
                throw new ArgumentNullException("key");
            }

            if (iv.IsNullOrWhiteSpace())
            {
                throw new ArgumentNullException("iv");
            }

            var inputByteArray = Convert.FromBase64String(text);
            var cipherBytes = default(byte[]);

            using (var aes = Rijndael.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = Encoding.UTF8.GetBytes(iv);
                aes.Padding = PaddingMode.PKCS7;

                var cryptoTransform = aes.CreateDecryptor();
                cipherBytes = cryptoTransform.TransformFinalBlock(inputByteArray, 0, inputByteArray.Length);
            }

            return Encoding.UTF8.GetString(cipherBytes);
        }
    }
}